<template>
  <div class="global-layer" ref="layer"></div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import * as THREE from 'three'
import EarthImg from '@/assets/images/global.jpg'
import lineFlyDraw from '@/utils/flyCreate'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

const fovState = 60
const radius = 70
let camera: THREE.Camera
const scene = new THREE.Scene()
const renderer = new THREE.WebGLRenderer({
  antialias: true
})
scene.add(new THREE.AxesHelper(100))

export default defineComponent({
  name: 'Global',
  data () {
    return {

    }
  },
  mounted () {
    this.initScene()
    // this.computedValue(12)
    // this.flyDrawCall()
  },
  methods: {
    layer () {
      return this.$refs.layer as HTMLElement
    },
    renderScene () {
      const layer = this.layer()
      renderer.setSize(layer.clientWidth, layer.clientHeight)
      renderer.setClearColor(0x000, 0)
      layer.appendChild(renderer.domElement)
      camera = new THREE.PerspectiveCamera(
        fovState,
        layer.clientWidth / layer.clientHeight,
        1,
        1000
      )
      camera.lookAt(0, 0, 0)
      camera.position.set(10, 10, 200)
      this.initOrbitControls()
      this.startGlobalRender()
    },
    startGlobalRender () {
      renderer.render(scene, camera)
      requestAnimationFrame(this.startGlobalRender)
    },
    initOrbitControls () {
      const controls = new OrbitControls(camera, renderer.domElement)
      controls.enableZoom = true
      controls.autoRotate = false
      controls.enablePan = true
      controls.enableDamping = true
      controls.autoRotateSpeed = 2
    },
    initScene () {
      const textureLoader = new THREE.TextureLoader()
      textureLoader.load(EarthImg, (texture) => {
        // 创建球体
        const geometry = new THREE.SphereGeometry(radius, 100, 100)
        const material = new THREE.MeshBasicMaterial({
          map: texture // 设置颜色贴图属性值
        })
        // 网格模型对象Mesh
        const mesh = new THREE.Mesh(geometry, material)
        // 唯一标识
        mesh.name = 'ballMain'
        // 添加到场景中
        scene.add(mesh)
        scene.add(this.drawLine())

        lineFlyDraw(scene)
        this.renderScene()
      })
    },
    flyDrawCall () {
      lineFlyDraw(scene)
      this.renderScene()
    },
    computedValue (r = 10) {
      const o = new THREE.Vector3(0, 0, 0)
      const m = new THREE.Vector3(4, 0, 0)
      const ray = new THREE.Ray(o, m)
      const d = m.distanceTo(o)
      console.log(d, r - d, r / d)
      const t = new THREE.Vector3(0, 0, 0)
      const c = ray.at(r / d, t)
      console.log(c.distanceTo(o))
      console.log(c)
      console.log(c.lerp(o, 0.2))
      // console.log(c.lerp(o, 0.5))

      console.log('---- v ----')
      const beta = new THREE.Vector3(0, 4, 0)
      console.log(o)
      console.log(m)
      console.log(beta)
      console.log(o.angleTo(m))
      console.log(o.angleTo(beta))
      console.log((o.angleTo(m) * 180) / Math.PI)
      console.log(o.clone().dot(m))
      console.log(m.clone().dot(o))
      console.log(Math.acos(o.clone().dot(m)))
      // const angle = (v0.angleTo(v3) * 180) / Math.PI
      // const aLen = angle * 0.013 * (1 - angle / (Math.PI * 90))
      // const hLen = angle * 1.230 * (1 - angle / (Math.PI * 90)) * angle
    },
    drawLine () {
      const geometry = new THREE.BufferGeometry()
      const r = 72
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      const arc = new THREE.CatmullRomCurve3([
        ...this.lerpAtVal(new THREE.Vector3(0, 0, r), new THREE.Vector3(0, r, 0), r, 0.2)
        // ...this.lerpAtVal(new THREE.Vector3(0, r, 0), new THREE.Vector3(0, 0, -r), r, 0.2)
      ])
      // getSpacedPoints是基类Curve的方法，返回一个vector2对象作为元素组成的数组
      const points = arc.getSpacedPoints(50) // 分段数50，返回51个顶点
      geometry.setFromPoints(points)// setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
      return new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: 0xffffff }))
    },
    lerpAtVal (start: THREE.Vector3, finish: THREE.Vector3, r: number, increase = 0, n = 16) {
      const ep = 1 / n
      const queue = []
      const val = increase / n
      const o = new THREE.Vector3(0, 0, 0)
      // console.log(start.clone().lerp(finish.clone(), 0.5))

      for (let i = 0; i < n; i++) {
        const c = start.clone().lerp(finish.clone(), ep * i)
        const ray = new THREE.Ray(o, c)
        const t = increase > 0 ? 1 + (val * i) : (1 - increase) + (val * (i + 1))
        queue.push(ray.at((r * t) / c.distanceTo(o), new THREE.Vector3(0, 0, 0)))
      }
      return queue
    }
  }
})
</script>

<style scoped lang="scss">
.global-layer {
  width: 960px;
  height: 720px;
}
</style>
